function freqAnalysis(subject, toi, foi, className)
    % performs frequency analysis. 
	% Uses preprocessed data stored in subject.subjectDir/subject.subjID_data.mat
	% subject: struct with subjectinfo. Should at least contain fields subjID, subjectDir, and MEGChannels (all not-rejected MEG channels)
	% toi: time of interest begintime:stepsize:endtime
	% foi: frequency of interest beginFreq:stepsize:endFreq
	% className: cell-array containing names of the to-be-analysed classes
	% Note that this script does not yet contain a way to directly couple className and triggerCode, so at the moment triggerCode is hard-coded in this script.
	% Stores results in subject.subjectDir/subject.subjID_freqAnalysis_className_foi_min(foi)-max(foi)-by-(foi(2)-foi(1))_toi_min(toi)-max(toi)-by-(toi(2)-toi(1)).mat
	
    eval(['load ', subject.subjectDir, '/', subject.subjID, '_data.mat data;']);

	[faceTrl sceneTrl bodyTrl toolTrl wordTrl] = deal([]);

	if strcmp(subject.subjID, 'P01')
		for i = 1 : length(data.trialinfo)
			if data.trialinfo(i) == 201 %faces
				faceTrl = [faceTrl i];
			elseif data.trialinfo(i) == 202 %scenes
				sceneTrl = [sceneTrl i];
			elseif data.trialinfo(i) == 203 %bodies
				bodyTrl = [bodyTrl i];
			elseif data.trialinfo(i) == 204 %tools
				toolTrl = [toolTrl i];
			elseif data.trialinfo(i) == 205 %words
				wordTrl = [wordTrl i];
			else
				error('ERROR: Invalid category trigger code.');
			end
		end
	else
		for i = 1 : length(data.trialinfo)
			if data.trialinfo(i) == 21 %faces
				faceTrl = [faceTrl i];
			elseif data.trialinfo(i) == 22 %scenes
				sceneTrl = [sceneTrl i];
			elseif data.trialinfo(i) == 23 %bodies
				bodyTrl = [bodyTrl i];
			elseif data.trialinfo(i) == 24 %tools
				toolTrl = [toolTrl i];
			elseif data.trialinfo(i) == 25 %words
				wordTrl = [wordTrl i];
			else
				error('ERROR: Invalid category trigger code.');
			end
		end
	end

	display(sprintf('Number of face trials is %i', size(faceTrl,2)));
	display(sprintf('Number of scene trials is %i', size(sceneTrl,2)));
	display(sprintf('Number of body trials is %i', size(bodyTrl,2)));
	display(sprintf('Number of tool trials is %i', size(toolTrl,2)));
	display(sprintf('Number of word trials is %i', size(wordTrl,2)));
	display(sprintf('\nTotal number of valid trials is %i', size(faceTrl,2) + size(sceneTrl,2) + size(bodyTrl,2) + size(toolTrl,2) + size(wordTrl,2)));

	if (size(faceTrl,2) + size(sceneTrl,2) + size(bodyTrl,2) + size(toolTrl,2) + size(wordTrl,2) ~= length(data.trialinfo)) %error in division
		error('ERROR: Sum of all defined trials is not equal to the total number of trials.');
	end

	if eval(['isempty(', className, 'Trl)'])
		display(sprintf('No data found for class %s', className));
	else
		cfg = [];
		cfg.channel = subject.MEGChannels;
		eval(['cfg.trials =', className, 'Trl;']);
		cfg.method = 'mtmconvol';
		cfg.output = 'pow';
		cfg.keeptrials = 'yes';
		cfg.taper = 'hanning';
		cfg.foi = foi;
		cfg.tapsmofrq = ones(1,size(cfg.foi,2)); % or 0.4*cfg.foi
		cfg.t_ftimwin = 0.5*ones(length(cfg.foi)); % or nCyclesPerWindow./cfg.foi
		cfg.toi = toi;
		cfg.pad = 'maxperlen';
		eval(['data_freqAnalysis_', className, ' = ft_freqanalysis(cfg, data);']);
		save([subject.subjectDir, '/', subject.subjID, '_freqAnalysis_', className,'_foi_', num2str(min(foi)), '-', num2str(max(foi)), '-by-', num2str(foi(2)-foi(1)), '_toi_', num2str(min(toi)), '-', num2str(max(toi)), '-by-', num2str(toi(2)-toi(1)), '.mat'] ,'data_freqAnalysis*', '-v7.3')
	end

end